﻿using System.Collections.Generic;
using UnityEngine;
namespace Gdmec.Cache
{
    public class AssetCache : MonoBehaviour
    {
        public class CacheAsset
        {
            public string path;
            public Object obj;
            public CacheAsset parent;
        }

        private Dictionary<string, CacheAsset> cache_assets = new Dictionary<string, CacheAsset>();

        public CacheAsset Set(string path, Object obj, CacheAsset parent = null)
        {
            CacheAsset cache;
            if (cache_assets.TryGetValue(path, out cache))
            {

            }
            else
            {
                cache = new CacheAsset();
                cache.path = path;
                cache.obj = obj;
                cache.parent = parent;
                cache_assets.Add(path, cache);
            }
            return cache;
        }

        public CacheAsset Set(string path, Object obj)
        {
            return Set(path, obj, null);
        }

        private CacheAsset GetCacheAsset(string path)
        {
            if (cache_assets.TryGetValue(path, out CacheAsset asset))
            {
                return asset;
            }
            else
            {
                var s0 = path.LastIndexOf('.');
                var s1 = path.LastIndexOf('/');
                if (s0 < s1)
                {
                    if (cache_assets.TryGetValue(path.Substring(0, s1), out CacheAsset temp_asset))
                    {
                        if (temp_asset.obj is AssetBundle)
                        {
                            var pack_obj = (temp_asset.obj as AssetBundle).LoadAsset(path.Substring(s1 + 1));
                            if (pack_obj != null)
                            {
                                return Set(path, pack_obj, temp_asset);
                            }
                        }
                    }
                }
            }
            return null;
        }

        public T Get<T>(string path) where T : Object
        {
            var asset = GetCacheAsset(path);
            if (asset != null) { return asset.obj as T; }
            return null;
        }

        public T Clone<T>(string path) where T : Object
        {
            var obj = Get<T>(path);
            if (obj != null) return Object.Instantiate(obj) as T;
            return null;
        }
    }
}
